<template>
  <div class="m-sign-img-box">
    <img v-if="value" :src="value" 
      :style="{
        height: height
      }"
      @click="showDialog()"/>
    <el-button v-if="!value" @click="showDialog()">点击签名</el-button>
  </div>
  <el-dialog
    class="m-sign-img-dialog"
    v-model="_d.visible"
    title="签名"
    width="800px"
    :destroy-on-close="true">
    <div class="sign-box">
      <canvas ref="signRef"
        width="750"
        height="300"
        @mousedown="handleStart"
        @mousemove="handleMove"
        @mouseup="handleEnd"></canvas>
    </div>
    <template #footer>
      <div class="dialog-footer">
        <el-button v-if="!disabled" type="primary" @click="onSubmit">生产签字图片</el-button>
        <el-button v-if="!disabled" @click="clearCanvas">清空画板</el-button>
        <el-button @click="_d.visible = false">取消</el-button>
      </div>
    </template>    
  </el-dialog>
</template>

<script setup>
import {ElMessage} from "element-plus";

const signRef = ref();

const emits = defineEmits(['update:modelValue', 'change'])
const props = defineProps({
  modelValue: {
    type: String,
    default: ''
  },
  disabled: {
    type: Boolean,
    default: false
  },
  // 生成图片高度
  height: {
    type: String,
    default: '32px'
  }
})

const _d = reactive({
  // 弹窗相关
  visible: false,

  isDraw: false, // 是否有画
  isDown: false,
  ctx: null,
  isDrawing: false,
  lastX: 0,
  lastY: 0,
  moveX: '',
  moveY: '',
})

const value = computed({
  get() {
    return props.modelValue;
  },
  set(val) {
    emits('update:modelValue', val);
  }
});

// 显示弹窗
function showDialog() {
  _d.visible = true;
  setTimeout(() => {
    _d.ctx = signRef.value.getContext("2d");
    _d.ctx.lineWidth = 3;
    _d.ctx.strokeStyle = '#000000';
    // 将图片绘制到 Canvas 上
    if(value.value) {
      let img = new Image();
      img.src = value.value;
      img.onload = () => {
        _d.ctx.drawImage(img, 0, 0);
      }
    }
  }, 20);
}

function handleStart(e) {
  if(props.disabled) {
    return false;
  }
  _d.isDrawing = true;
  // 取出x、y的值
  _d.lastX = e.offsetX;
  _d.lastY = e.offsetY;
  // 绘制线条起点
  _d.ctx.beginPath()
  _d.ctx.moveTo(_d.lastX, _d.lastY)
  // 起点与移动的连接断开
  _d.moveX = 0
  _d.moveY = 0
}
function handleMove(e) {
  if (!_d.isDrawing) return;
  _d.isDraw = true; // 确定已画
  _d.ctx.beginPath();
  _d.ctx.moveTo(_d.lastX, _d.lastY);
  _d.ctx.lineTo(e.offsetX, e.offsetY);
  _d.ctx.stroke();
  _d.lastX = e.offsetX;
  _d.lastY = e.offsetY;
}
function handleEnd() {
  if (!_d.isDrawing) return;
  _d.isDrawing = false;
}
function clearCanvas() {
  _d.ctx.clearRect(0, 0, signRef.value.width, signRef.value.height);
  _d.isDraw = false;
}

// 确定
function onSubmit() {
  if(!_d.isDraw) {
    ElMessage.error('请签字后再保存');
    return;
  }
  // 使用canvas的toDataURL()方法，将画布内容转换为base64格式的图片数据:
  let imgData = signRef.value.toDataURL('image/png');
  value.value =  imgData;
  _d.visible = false;
}
</script>
<style lang="scss">
  .m-sign-img-box {
    display: flex;
    flex-wrap: wrap;
    align-items: flex-end;
    img {
      cursor: pointer;
      height: 32px;
      &:hover {
        box-shadow: 0 0 5px rgba(0,0,0,0.12);
      }
    }
  }

  .m-sign-img-dialog {
    .el-dialog__header {
      margin: 0;
      padding: 16px 24px;
      line-height: 20px;
      border-bottom: 1px solid #e8e8e8;
      .el-dialog__headerbtn {
        top: 2px;
      }
    }
    .el-dialog__footer {
      padding: 10px 16px;
      border-top: 1px solid #e8e8e8;
    }
    .el-dialog__body {
      padding: 20px 0 !important;
      display: flex;
      justify-content: center;
    }
    .sign-box {
      border: 1px solid #e8e8e8;
      canvas {
        display: block;
        margin: 0 auto;
      }
    }
    .dialog-footer {
      text-align: right;
    }
  }
</style>
